package com.mjk.common.tools.monitor.impl;

import com.mjk.common.core.dcc.DccClient;
import com.mjk.common.core.dcc.DccWatcher;
import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.tools.monitor.IMonitor;
import com.mjk.common.util.ComputerUtils;
import com.mjk.common.util.ObjectUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.ArrayList;
import java.util.List;

/**
 * 服务监控实现类 用于监控可用的服务 基于zookepper实现
 * @author Administrator
 *
 */
public class ZookepperMonitor extends DccClient implements IMonitor, ApplicationContextAware {
	//获取服务启动的端口号
	@Value(value="${server.port:8080}")
	private String nodeName ;
	
	@Value(value="${bee.application.name:}")
	private String serviceName;
	
	private ZooKeeper zk;
	/**
	 * 服务列表
	 */
	private List<String> serviceList = new ArrayList<>();
	/**
	 * 根节点
	 */
	public  String ROOT_PATH = "/bee-service";

	public ZookepperMonitor(String zkHost, int timeout) {
		super(zkHost, timeout);
		try{
			zk = getHolder().connect();
			//初始化根节点
			Stat stat = zk.exists(ROOT_PATH, false);
			if (stat == null) {
				this.zk.create(ROOT_PATH, new byte[0],
						ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			}
			//节点监听
			registNodeListener(ROOT_PATH, new DccWatcher.NodeListener() {
				@Override
				public void onRefreshChildren(List<String> children) {
					serviceList = children;
				}			
			});
		}catch(Exception e){
			BizLogger.error(e);
			Thread.currentThread().interrupt();
		}
	}
	/**
	 * 在服务 启动过程中，向ZK中注册服务启动消息
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		ComputerUtils.ComputerInfo info = ComputerUtils.getComputerInfo();
		info.setPort(nodeName);
		if(ObjectUtils.isEmpty(serviceName)) {
			info.setServiceName(info.getIp()+":"+info.getPort());
		}else {
			info.setServiceName(serviceName);
		}
		writeData(ROOT_PATH+"/"+info.getIp()+":"+nodeName, info,false);
	}
		
	@Override
	public List<ComputerUtils.ComputerInfo> getServices(String name) {
		List<ComputerUtils.ComputerInfo> result = new ArrayList<>();
		for(String node : serviceList) {
			ComputerUtils.ComputerInfo info = GsonUtils.json2Bean(readData(ROOT_PATH+"/"+ node), ComputerUtils.ComputerInfo.class) ;
		
			result.add(info);
		}
		return result;
	}
	
	/**
	 * 每隔5秒进行数据更新
	 */
	@Scheduled(cron = "0/5 * * * * ?")
	public void upServiceInfo() {
		ComputerUtils.ComputerInfo info = ComputerUtils.getComputerInfo();
		info.setPort(nodeName);
		if(ObjectUtils.isEmpty(serviceName)) {
			info.setServiceName(info.getIp()+":"+info.getPort());
		}else {
			info.setServiceName(serviceName);
		}
		writeData(ROOT_PATH+"/"+info.getIp()+":"+nodeName, info,false);
	}
}
